///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.rectangular.renderers
{
  import flash.display.Graphics;
  import flash.geom.Rectangle;
  
  import ilog.gauges.gaugesClasses.rectangular.RectangularGaugeElement;
  import ilog.utils.CSSUtil;
  
  import mx.graphics.GradientEntry;
  import mx.graphics.IFill;
  import mx.graphics.LinearGradient;
  import mx.graphics.Stroke;
  import mx.styles.CSSStyleDeclaration;

  /**
   * Specifies the stroke for the rectangle.
   * This style must be an instance of an implementation of the <code>IStroke</code> interface.
   * 
   * @default undefined 
   */
  [Style(name="stroke", type="mx.graphics.IStroke", inherit="no")]

  /**
   * Specifies the fill for the rectangle.
   * This style must be an instance of an implementation of the <code>IFill</code> interface.
   * 
   * @default 0xFF0000 
   */
  [Style(name="fill", type="mx.graphics.IFill", inherit="no")]

  /**
   * A basic rectangle renderer to use in rectangular gauges. You can customize the
   * fill and stroke of this visual element. Inherited <code>x</code>, <code>y</code>, <code>width</code>, and <code>height</code> 
   * properties are used for positioning.
   * 
   * @mxml
   *  
   * <p>The <code>&lt;ilog:RectangleRenderer&gt;</code> tag inherits all the properties
   * of its parent classes and adds the following properties:</p>
   *  
   * <pre>
   * &lt;ilog:RectanguleRenderer
   *   <strong>Properties</strong>
   *   rounded="false"
   *   radius="2"
   * 
   *   <strong>Styles</strong>
   *   fill="IFill; a grey-style radial gradient"
   *   stroke="Stroke; no default"
   * /&gt;
   * </pre>
   * 
   */ 
  public class RectangleRenderer extends RectangularGaugeElement
  {      
    /**
     *  @private
     */
    private static var stylesInited:Boolean = initStyles(); 

    /**
     *  @private
     */
    private static function initStyles():Boolean
    {
      var pStyle:CSSStyleDeclaration =
        CSSUtil.createSelector("RectangleRenderer");   
            
      pStyle.defaultFactory = function():void {
        var fill:LinearGradient = new LinearGradient();         
        var g1:GradientEntry = new GradientEntry(0xEEEEEE, 0.0, 1);
        var g2:GradientEntry = new GradientEntry(0xFFFFFF, 0.4, 1);
        var g3:GradientEntry = new GradientEntry(0xCCCCCC, 0.8, 1);
          
        fill.entries = [ g1, g2, g3 ];
        this.fill = fill;         
      }
      
      return true;
    }
    
    /**
     * Constructor
     */
    public function RectangleRenderer()
    {
      
    }
    
    private var _rounded:Boolean = false;
    
    [Inspectable(category="Gauge")]
    
    /**
     * Specifies whether the rectangle will be drawn with rounded corners or not.
     * 
     * @default false
     * @see #radius
     */
    public function get rounded():Boolean
    {
      return _rounded;
    }
    
    /**
     * @private
     */
    public function set rounded(value:Boolean):void
    {
      _rounded = value;
      invalidateDisplayList();
    }            
    
    private var _radius:Number = 2;
    
    [Inspectable(category="Gauge")]    
    
    /**
     * When <code>rounded</code> is <code>true</code>, this function specifies the radius of 
     * the rounded corners. This property has no effect if <code>rounded</code>
     * is <code>false</code>.
     * 
     * @default 2
     */
    public function get radius():Number
    {
      return _radius;
    }
    
    /**
     * @private
     */
    public function set radius(value:Number):void
    {
      _radius = value;
      invalidateDisplayList() 
    }

    /**
     * Draws the rectangle.
     *
     * @param unscaledWidth Specifies the width, in pixels, of the component
     * in the component's coordinates, regardless of the value of the
     * <code>scaleX</code> property of the component.
     *
     * @param unscaledHeight Specifies the height, in pixels, of the component
     * in the component's coordinates, regardless of the value of the
     * <code>scaleY</code> property of the component.   
     */    
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
      var g:Graphics = graphics;
 
      var fill:IFill = CSSUtil.fillFromStyle(getStyle("fill"));
      var stroke:Stroke = getStyle("stroke");
      
      g.clear();
      if (stroke)
        stroke.apply(g);     
      if (fill) {
        fill.begin(g, new Rectangle(0, 0, unscaledWidth, unscaledHeight));        
      }
      if (!rounded)
        g.drawRect(0, 0, unscaledWidth, unscaledHeight);
      else
        g.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 2*radius, 2*radius);      
      if (fill)
        fill.end(g);
    }
  }
}
